home *** CD-ROM | disk | FTP | other *** search
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <time.h>
- #include "lutil.h"
- #include "xutil.h"
- #include "mkrfcmsg.h"
- #include "rfcmsg.h"
- #include "areas.h"
- #include "falists.h"
- #include "config.h"
-
- #define BOUNDARY 79
-
- int num_echo=0,num_mail=0;
- extern char *version;
- extern FILE *nb;
- extern faddr pktfrom;
-
- extern char *rfcdate(time_t);
- extern long sequencer(void);
- extern char *lookup(char *);
- extern char *backalias(faddr *);
-
- char *rfcmsgid(msgid)
- char *msgid;
- {
- static char buf[128],*p,*q;
- unsigned long id=0L;
- faddr *ta=NULL;
-
- if ((p=strrchr(msgid,' ')))
- {
- *p='\0';
- sscanf(p+1,"%lx",&id);
- ta=parsefnode(msgid);
- *p=' ';
- }
- if (id != 0L)
- {
- if (ta)
- {
- sprintf(buf,"<%lu@%s>",id,ascinode(ta,0x1f));
- }
- else
- {
- p=xstrcpy(msgid);
- if ((q=strchr(p,' '))) *q='\0';
- sprintf(buf,"<%lu@%s>",id,p);
- free(p);
- }
- }
- else
- {
- sprintf(buf,"<%lu@%s>",sequencer(),
- ascinode(whoami->addr,0x1f));
- }
- tidy_faddr(ta);
- return buf;
- }
-
- /* check address for localness, substitute alises and replace it *in place* */
-
- void substitute(buf)
- char *buf;
- {
- faddr *fa;
- char *l,*r,*p=NULL;
- int inquotes,inbrackets;
-
- debug(6,"to address before subst: \"%s\"",buf);
- if ((l=strchr(buf,'<')) && (r=strchr(buf,'>')) && (l < r))
- {
- l++;
- *r='\0';
- }
- else l=buf;
- while (*l == ' ') l++;
- for (r=l,inquotes=0,inbrackets=0;*r;r++) switch (*r)
- {
- case '"': inquotes=(!inquotes); break;
- case ',':
- case ' ': if (!inquotes && !inbrackets) *r='\0'; break;
- case '(': if (!inquotes) inbrackets++; break;
- case ')': if (!inquotes && inbrackets) inbrackets--; break;
- default: break;
- }
- if ((fa=parsefaddr(l)))
- {
- if (is_local(fa))
- {
- sprintf(buf,"%s",fa->name);
- if (!strchr(buf,'@') && (p=strrchr(buf,'%')))
- *p='@';
- if (!strchr(buf,'@'))
- {
- if ((p=lookup(buf)))
- strcpy(buf,p);
- else for (p=buf;*p;p++)
- if (*p == ' ') *p='.';
- }
- if (!strcasecmp(buf,"sysop")) strcpy(buf,"postmaster");
- }
- else
- {
- sprintf(buf,"%s",ascinode(fa,0x7f));
- }
- tidy_faddr(fa);
- }
- else
- {
- for (r=buf;*l;l++,r++) *r=*l;
- *(r+1)='\0';
- }
- if (buf[0] == '\0') strcpy(buf,"postmaster");
- debug(6,"to address after subst: \"%s\"",buf);
- return;
- }
-
- static char *flnm[] = {
- "PVT","CRS","RCV","SNT","ATT","TRN","ORP","K/S",
- "LOC","HLD","RSV","FRQ","RRQ","RRC","ARQ","FUP"
- };
-
- /* from, to, subj, orig, mdate, flags, file, offset, kluges */
-
- int mkrfcmsg(f,t,subj,orig,mdate,flags,fp,endoff,kmsg)
- faddr *f,*t;
- char *subj,*orig;
- time_t mdate;
- int flags;
- FILE *fp;
- off_t endoff;
- rfcmsg *kmsg;
- {
- char buf[BUFSIZ];
- char cmd[BUFSIZ];
- char *p,*l,*r,*b;
- char *newsgroup=NULL,*distribution=NULL;
- char c;
- int count,i,rrq;
- rfcmsg *msg=NULL,*tmsg;
- FILE *pip;
- struct stat stbuf;
- int newsmode,pass,rc;
- faddr *ta;
- fa_list *ftnpath=NULL,*tfa;
- time_t now;
- int lines;
- char lineshdr[16];
-
- msg=parsrfc(fp);
-
- if (kmsg && !strcmp(kmsg->key,"AREA"))
- {
- ngdist(kmsg->val,&newsgroup,&distribution);
- if (!newsgroup)
- {
- tidyrfc(msg);
- return 0;
- }
- newsmode=1;
- }
- else newsmode=0;
- debug(5,"Got %s message",newsmode?"echo":"netmail");
-
- if ((p=hdr("INTL",kmsg)))
- {
- strncpy(buf,p,sizeof(buf)-1);
- l=strtok(buf," \n");
- r=strtok(NULL," \n");
- if ((ta=parsefnode(l)))
- {
- t->point=ta->point;
- t->node=ta->node;
- t->net=ta->net;
- t->zone=ta->zone;
- if (ta->domain)
- {
- if (t->domain) free(t->domain);
- t->domain=ta->domain;
- ta->domain=NULL;
- }
- tidy_faddr(ta);
- }
- if ((ta=parsefnode(r)))
- {
- f->point=ta->point;
- f->node=ta->node;
- f->net=ta->net;
- f->zone=ta->zone;
- if (ta->domain)
- {
- if (f->domain) free(f->domain);
- f->domain=ta->domain;
- ta->domain=NULL;
- }
- tidy_faddr(ta);
- }
- }
-
- if ((p=hdr("FMPT",kmsg))) f->point=atoi(p);
- if (f->domain == NULL) f->domain=xstrcpy(whoami->addr->domain);
- if ((p=hdr("TOPT",kmsg))) t->point=atoi(p);
- if (t->domain == NULL) t->domain=xstrcpy(whoami->addr->domain);
-
- if (!newsmode)
- {
- p=hdr("Resend-To",msg);
- if (p == NULL) p=hdr("To",msg);
- if (p == NULL) p=hdr("RFC-Resend-To",kmsg);
- if (p == NULL) p=hdr("RFC-To",kmsg);
- if (p)
- {
- while (*p == ' ') p++;
- strncpy(buf,p,sizeof(buf)-1);
- if (*(p=buf+strlen(buf)-1) == '\n') *p='\0';
- }
- else sprintf(buf,"%s",ascinode(t,0x7f));
- substitute(buf);
- loginf("mail from %s to %s",ascfnode(f,0x7f),buf);
- }
-
- if ((newsmode) && (nb == NULL))
- {
- if (verbose) nb=fopen(tempnam("/tmp/ifmail","N."),"w");
- else nb=popen(rnews,"w");
- if (nb == NULL)
- {
- logerr("$Could non open (pipe) output for news");
- tidyrfc(msg);
- return 2;
- }
- }
-
- if (newsmode)
- {
- if ((pip=tmpfile()) == NULL)
- {
- logerr("$Cannot open second temporary file");
- tidyrfc(msg);
- return 2;
- }
- }
- else
- {
- sprintf(cmd,"%s %s",sendmail,buf);
- debug(2,"popen(\"%s\",\"w\")",cmd);
- if (verbose) pip=fopen(tempnam("/tmp/ifmail","M."),"w");
- else pip=popen(cmd,"w");
- if (pip == NULL)
- {
- logerr("$Could non open (pipe) output for mail");
- tidyrfc(msg);
- return 2;
- }
- }
-
-
- if (newsmode)
- {
- num_echo++;
- fill_list(&ftnpath,hdr("PATH",kmsg));
- fprintf(pip,"Path: ");
-
- fprintf(pip,"%s!",ascinode(whoami->addr,0x07));
- fprintf(pip,"%s!",ascinode(&pktfrom,0x07));
- if (ftnpath)
- for (tfa=ftnpath->next;tfa;tfa=tfa->next)
- fprintf(pip,"%s!",ascinode(tfa->addr,0x06));
- else
- {
- fprintf(pip,"%s!",ascinode(f,0x07));
- }
- tidy_falist(&ftnpath);
- if ((p=hdr("Path",msg)) == NULL)
- p=hdr("RFC-Path",kmsg);
- if (p)
- {
- while (*p == ' ') p++;
- fprintf(pip,"%s",p);
- }
- else fprintf(pip,"%s\n",ascinode(f,0x40));
-
- fprintf(pip,"Newsgroups: %s\n",newsgroup);
- if (distribution)
- fprintf(pip,"Distribution: %s\n",distribution);
- if (t->name == NULL) t->name=xstrcpy("All");
- p=hdr("Comment-To",msg);
- if (p == NULL) p=hdr("X-Comment-To",msg);
- if (p == NULL) p=hdr("To",msg);
- if (p)
- fprintf(pip,"X-Comment-To:%s",p);
- else
- {
- if (p == NULL) p=hdr("RFC-X-Comment-To",kmsg);
- if (p == NULL) p=hdr("RFC-Comment-To",kmsg);
- if (p == NULL) p=hdr("RFC-To",kmsg);
- if (p) fprintf(pip,"X-Comment-To: %s",p);
- else fprintf(pip,"X-Comment-To: %s\n",ascinode(t,0xff));
- }
- }
- else
- {
- num_mail++;
- time(&now);
- #ifdef NEED_UUCPFROM
- fprintf(pip,"From %s!",ascinode(f,0x3f));
- fprintf(pip,"%s %s",ascinode(f,0x40),ctime(&mdate));
- #endif
- fprintf(pip,"Received: from %s ",ascinode(f,0x3f));
- fprintf(pip,"by %s\n",ascinode(bestaka_s(f),0x3f));
- fprintf(pip,"\twith FTN (ifmail v.%s) id AA%u; %s\n",
- version,getpid(),rfcdate(now));
- for (tmsg=msg;tmsg;tmsg=tmsg->next)
- if (!strcasecmp(tmsg->key,"Received"))
- fprintf(pip,"%s:%s",tmsg->key,tmsg->val);
- if (hdr("Apparently-To",msg) == NULL)
- fprintf(pip,"Apparently-To: %s\n",buf);
- if (t->name == NULL) t->name=xstrcpy("Sysop");
- p=hdr("Resend-To",msg);
- if (p == NULL) p=hdr("To",msg);
- if (p)
- fprintf(pip,"To:%s",p);
- else
- {
- if (p == NULL) p=hdr("RFC-Resend-To",kmsg);
- if (p == NULL) p=hdr("RFC-To",kmsg);
- if (p) fprintf(pip,"To: %s",p);
- else fprintf(pip,"To: %s\n",ascinode(t,0xff));
- }
- }
-
- if ((p=hdr("From",msg))) fprintf(pip,"From:%s",p);
- else if ((p=hdr("RFC-From",kmsg))) fprintf(pip,"From: %s",p);
- else fprintf(pip,"From: %s\n",ascinode(f,0xff));
-
- if ((p=hdr("Reply-To",msg))) fprintf(pip,"Reply-To:%s",p);
- else if ((p=hdr("RFC-Reply-To",kmsg))) fprintf(pip,"Reply-To: %s",p);
- else if (((p=backalias(f))) && myfqdn)
- fprintf(pip,"Reply-To: %s@%s\n",p,myfqdn);
- else if ((p=hdr("REPLYADDR",kmsg))) fprintf(pip,"Reply-To: %s",p);
-
- if ((p=hdr("Date",msg))) fprintf(pip,"Date:%s",p);
- else if ((p=hdr("RFC-Date",kmsg))) fprintf(pip,"Date: %s",p);
- else fprintf(pip,"Date: %s\n",rfcdate(mdate));
-
- if ((p=hdr("Subject",msg))) fprintf(pip,"Subject:%s",p);
- else if ((p=hdr("RFC-Subject",kmsg))) fprintf(pip,"Subject: %s",p);
- else if (subj && (strspn(subj," \t\n\r") != strlen(subj)))
- fprintf(pip,"Subject: %s\n",subj);
- else fprintf(pip,"Subject: <none>\n");
-
- if ((p=hdr("Message-ID",msg))) fprintf(pip,"Message-ID:%s",p);
- else if ((p=hdr("RFC-Message-ID",kmsg))) fprintf(pip,"Message-ID: %s",p);
- else if ((p=hdr("MSGID",kmsg))) fprintf(pip,"Message-ID: %s\n",rfcmsgid(p));
- else fprintf(pip,"Message-ID: <%lu@%s>\n",mdate,
- ascinode(f,0x1f));
-
- if (newsmode)
- {
- if ((p=hdr("References",msg)))
- fprintf(pip,"References:%s",p);
- else if ((p=hdr("RFC-References",kmsg)))
- fprintf(pip,"References: %s",p);
- else if ((p=hdr("REPLY",kmsg)))
- fprintf(pip,"References: %s\n",rfcmsgid(p));
- }
- else
- {
- if ((p=hdr("In-Reply-To",msg)))
- fprintf(pip,"In-Reply-To:%s",p);
- else if ((p=hdr("RFC-In-Reply-To",kmsg)))
- fprintf(pip,"In-Reply-To: %s",p);
- else
- {
- if ((p=hdr("REPLY",kmsg)))
- fprintf(pip,"In-Reply-To: %s\n",rfcmsgid(p));
- }
- }
-
- if ((p=hdr("Organization",msg))) fprintf(pip,"Organization:%s",p);
- else if ((p=hdr("RFC-Organization",kmsg)))
- fprintf(pip,"Organization: %s",p);
- else if (orig) fprintf(pip,"Organization: %s\n",orig);
-
- for (tmsg=msg;tmsg;tmsg=tmsg->next)
- {
- if (strcasecmp(tmsg->key,"X-Body-Start") &&
- strcasecmp(tmsg->key,"Lines") &&
- strcasecmp(tmsg->key,"Path") &&
- strcasecmp(tmsg->key,"Received") &&
- strcasecmp(tmsg->key,"From") &&
- strcasecmp(tmsg->key,"To") &&
- strcasecmp(tmsg->key,"Comment-To") &&
- strcasecmp(tmsg->key,"X-Comment-To") &&
- strcasecmp(tmsg->key,"Date") &&
- strcasecmp(tmsg->key,"Subject") &&
- strcasecmp(tmsg->key,"Reply-To") &&
- strcasecmp(tmsg->key,"In-Reply-To") &&
- strcasecmp(tmsg->key,"References") &&
- strcasecmp(tmsg->key,"Organization") &&
- strcasecmp(tmsg->key,"Newsgroups") &&
- strcasecmp(tmsg->key,"Distribution") &&
- strcasecmp(tmsg->key,"Message-ID"))
- fprintf(pip,"%s:%s",tmsg->key,tmsg->val);
- }
-
- if ((p=hdr("X-FTN-FLAGS",msg))) strncpy(buf,p,sizeof(buf)-(4*16)-1);
- else buf[0]='\0';
- if (*(p=buf+strlen(buf)-1) == '\n') *p='\0';
- for (i=0;i<16;i++) if (flags & (1 << i))
- {
- for (p=buf;*p;p++) if (!strncasecmp(p,flnm[i],3)) break;
- if (*p == '\0') sprintf(p," %s",flnm[i]);
- }
- if (buf[0]) fprintf(pip,"X-FTN-FLAGS:%s\n",buf);
- rrq=0;
- for (p=buf;*p;p++) if (!strncasecmp(p,flnm[12],3)) rrq=1;
- if (rrq && !hdr("RFC-Return-Receipt-To",kmsg) &&
- !hdr("Return-Receipt-To",msg))
- {
- if ((p=hdr("REPLYADDR",kmsg)))
- fprintf(pip,"Return-Receipt-To: %s",p);
- else if (((p=backalias(f))) && myfqdn)
- fprintf(pip,"Reply-To: %s@%s\n",p,myfqdn);
- else fprintf(pip,"Return-Receipt-To: %s\n",ascinode(f,0x7f));
- }
-
- for (tmsg=kmsg;tmsg;tmsg=tmsg->next)
- {
- if (strcasecmp(tmsg->key,"INTL") &&
- strcasecmp(tmsg->key,"FMPT") &&
- strcasecmp(tmsg->key,"TOPT") &&
- strcasecmp(tmsg->key,"REPLY") &&
- strcasecmp(tmsg->key,"MSGID") &&
- strcasecmp(tmsg->key,"FLAGS") &&
- strcasecmp(tmsg->key,"RFC-Lines") &&
- strcasecmp(tmsg->key,"RFC-Path") &&
- strcasecmp(tmsg->key,"RFC-Received") &&
- strcasecmp(tmsg->key,"RFC-From") &&
- strcasecmp(tmsg->key,"RFC-To") &&
- strcasecmp(tmsg->key,"RFC-Comment-To") &&
- strcasecmp(tmsg->key,"RFC-X-Comment-To") &&
- strcasecmp(tmsg->key,"RFC-Date") &&
- strcasecmp(tmsg->key,"RFC-Subject") &&
- strcasecmp(tmsg->key,"RFC-Reply-To") &&
- strcasecmp(tmsg->key,"RFC-In-Reply-To") &&
- strcasecmp(tmsg->key,"RFC-References") &&
- strcasecmp(tmsg->key,"RFC-Organization") &&
- strcasecmp(tmsg->key,"RFC-Newsgroups") &&
- strcasecmp(tmsg->key,"RFC-Distribution") &&
- strcasecmp(tmsg->key,"RFC-Message-ID"))
- if (!strncmp(tmsg->key,"RFC-",4))
- fprintf(pip,"%s: %s",tmsg->key+4,tmsg->val);
- else
- fprintf(pip,"X-FTN-%s: %s",tmsg->key,tmsg->val);
- }
-
- fprintf(pip,"\n");
- lines=0;
- if ((p=hdr("X-Body-Start",msg)))
- {
- lines++;
- fputs(p,pip);
- }
- pass=1;
- count=0;
- while(fgets(buf,sizeof(buf)-1,fp) && pass)
- {
- if (ftell(fp) > endoff)
- {
- debug(5,"line \"%s\" past message end %ld",
- buf,endoff);
- pass=0;
- }
- if (pass)
- {
- p=buf;
- b=NULL;
- while ((c=*p++))
- {
- switch (c)
- {
- case ' ': b=p-1; break;
- case '\n': b=NULL; count=0; lines++; break;
- }
- if (count++ > BOUNDARY)
- {
- if (b)
- {
- *b='\n';
- p=b+1;
- b=NULL;
- lines++;
- }
- count=0;
- }
- }
- fputs(buf,pip);
- }
- }
-
- if (newsmode)
- {
- sprintf(lineshdr,"Lines: %d\n",lines);
- rewind(pip);
- fstat(fileno(pip),&stbuf);
- fprintf(nb,"#! rnews %lu\n",stbuf.st_size+strlen(lineshdr));
- while (fgets(buf,sizeof(buf)-1,pip) && (buf[0] != '\n'))
- fputs(buf,nb);
- fputs(lineshdr,nb);
- fputs(buf,nb);
- while (fgets(buf,sizeof(buf)-1,pip))
- fputs(buf,nb);
- }
- if ((rc=fclose(pip)))
- {
- logerr("$fclose of transport pipe or tmp file returned %d",rc);
- }
- tidyrfc(msg);
- return rc;
- }
-